<template>
  <a-modal
    v-model="syslistchange"
    title="系统菜单权限修改"
    :width="800"
    :footer="footerContent"
    @cancel="handleCancel"
  >
    <div :style="{ background: '#fff', padding: '24px', minHeight: '280px' }">
      <a-row :gutter="16">
        <a-col :span="24">
          <div class="right-panel">
            <a-tree
              checkable
              :checkStrictly="true"
              :treeData="menuTreeData"
              :checkedKeys="selectedMenuKeys"
              :defaultExpandAll="true"
              :childrenField="'children'"
              @check="onMenuCheck"
            />
          </div>
        </a-col>
      </a-row>
    </div>
  </a-modal>
</template>

<script>
import { getRoleSysMenuTreeListEnabled, getSysMenuTreeListEnabled, editSysRoleAndMenu } from '@/api/common/api'

export default {
  props: {
    roleId: {
      type: [String, Number],
      required: true
    }
  },
  data() {
    return {
      syslistchange: false,
      menuTreeData: [],
      selectedMenuKeys: [],
      allMenuKeys: [],
      isInit: false,
      footerContent: (
        <div style="text-align: right;">
          <a-button onClick={() => this.handleCancel()} style="margin-right: 8px;">取消</a-button>
          <a-button type="primary" onClick={() => this.handleSave()}>保存</a-button>
        </div>
      ),
    }
  },
  watch: {
    syslistchange(val) {
      if (val) this.loadMenuTree()
    },
    roleId(val) {
      if (this.syslistchange) this.loadMenuTree()
    }
  },
  methods: {
    getCurrentAppId() {
      try {
        const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
        return userInfo.appId || ''
      } catch (e) {
        return ''
      }
    },
    async loadMenuTree() {
      const appId = this.getCurrentAppId()
      const [allMenusRes, roleMenusRes] = await Promise.all([
        getSysMenuTreeListEnabled({ appId }),
        getRoleSysMenuTreeListEnabled({ roleId: this.roleId, appId })
      ])
      function convertTreeData(list) {
        return (list || []).map(item => ({
          title: item.text || item.name || '---',
          key: item.id,
          children: item.children ? convertTreeData(item.children) : []
        }))
      }
      this.menuTreeData = convertTreeData(allMenusRes.result || [])
      function collectAllKeys(tree) {
        let keys = []
        tree.forEach(node => {
          keys.push(node.key)
          if (node.children && node.children.length) {
            keys = keys.concat(collectAllKeys(node.children))
          }
        })
        return keys
      }
      this.allMenuKeys = collectAllKeys(this.menuTreeData)
      function collectAllCheckedKeys(tree) {
        let keys = []
        tree.forEach(node => {
          keys.push(node.id)
          if (node.children && node.children.length) {
            keys = keys.concat(collectAllCheckedKeys(node.children))
          }
        })
        return keys
      }
      const rawKeys = collectAllCheckedKeys(roleMenusRes.result || [])
      this.isInit = true
      this.selectedMenuKeys = rawKeys.filter(k => this.allMenuKeys.includes(k))
    },
    // 递归获取某节点下所有子节点key
    getAllChildKeysByKey(key, tree = this.menuTreeData) {
      let result = []
      function findNodeAndCollect(nodeList) {
        for (const node of nodeList) {
          if (node.key === key) {
            collectAllKeys(node)
            break
          } else if (node.children && node.children.length) {
            findNodeAndCollect(node.children)
          }
        }
      }
      function collectAllKeys(node) {
        if (node.children && node.children.length) {
          node.children.forEach(child => {
            result.push(child.key)
            collectAllKeys(child)
          })
        }
      }
      findNodeAndCollect(tree)
      return result
    },
    onMenuCheck(checkedKeys, e) {
      let keys = Array.isArray(checkedKeys) ? checkedKeys : (checkedKeys.checked || [])
      // 只勾选用户实际点击的项，不做任何上下级联动
      keys = keys.filter(k => this.allMenuKeys.includes(k))
      this.selectedMenuKeys = keys
    },
    handleCancel() {
      this.syslistchange = false
    },
    resetMenuCheck() {
      this.selectedMenuKeys = []
    },
    async handleSave() {
      const appId = this.getCurrentAppId()
      const filteredKeys = this.selectedMenuKeys.filter(k => this.allMenuKeys.includes(k))
      const params = {
        id: this.roleId,
        appId,
        terminalid: 0,
        ids: filteredKeys
      }
      try {
        await editSysRoleAndMenu(params)
        this.$message.success('权限保存成功')
        this.syslistchange = false
      } catch (e) {
        this.$message.error('权限保存失败')
      }
    },
  }
}
</script>

<style scoped>
.right-panel {
  padding: 16px;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  min-height: 400px;
  overflow-y: auto;
}
.action-buttons {
  margin-top: 16px;
  text-align: right;
}
.expand-collapse-buttons {
  margin-bottom: 16px;
  text-align: left;
}
</style>